#include "tcp_server.h"
#include "lwip/tcp.h"
#include "system.h"
#include "lwip.h"
#define LOG_TAG "TCP_Server"

#define TCP_SERVER_PORT 5000
#define TCP_SERVER_PRIORITY 5
#define TCP_SERVER_STACK_SIZE 1024

/* 客户端连接控制块 */
static struct tcp_pcb *client_pcb = NULL;
TaskHandle_t TCP_Server_Handle = NULL;

/* 数据接收回调函数声明 */
static err_t tcp_server_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err);
static err_t tcp_server_sent(void *arg, struct tcp_pcb *tpcb, u16_t len);
static void tcp_server_err(void *arg, err_t err);
static void process_received_data(struct tcp_pcb *tpcb, struct pbuf *p);
static err_t tcp_server_accept(void *arg, struct tcp_pcb *newpcb, err_t err);

/**
 * @brief  TCP服务端任务
 * @param  pvParameters: 任务参数
 * @retval None
 */
static void tcp_server_task(void *pvParameters)
{
    struct tcp_pcb *pcb = NULL;
    err_t err;

    /* 创建TCP控制块 */
    pcb = tcp_new();
    if (pcb == NULL)
    {
        log_e("Failed to create pcb\n");
        vTaskDelete(NULL);
        return;
    }

    /* 绑定本地端口 */
    err = tcp_bind(pcb, IP_ADDR_ANY, TCP_SERVER_PORT);
    if (err != ERR_OK)
    {
        log_e("Failed to bind port %d\n", TCP_SERVER_PORT);
        tcp_close(pcb);
        vTaskDelete(NULL);
        return;
    }

    /* 开始监听 */
    pcb = tcp_listen(pcb);
    if (pcb == NULL)
    {
        log_e("Failed to listen\n");
        tcp_close(pcb);
        vTaskDelete(NULL);
        return;
    }

    /* 设置接受连接回调 */
    tcp_accept(pcb, tcp_server_accept);

    log_w("TCP server started on port %d\n", TCP_SERVER_PORT);

    /* 任务主循环 */
    for (;;)
    {
        vTaskDelay(pdMS_TO_TICKS(1000)); // 定期唤醒检查连接状态

        // 可以在这里添加其他服务端逻辑
        // 检查网络接口状态
        if (!netif_is_up(&gnetif))
        {
            log_e("Network interface down\n");
        }
    }
}

/**
 * @brief  接受新连接回调
 * @param  arg: 用户参数
 * @param  newpcb: 新连接的控制块
 * @param  err: 错误码
 * @retval err_t: 错误码
 */
static err_t tcp_server_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
{
    LWIP_UNUSED_ARG(arg);
    LWIP_UNUSED_ARG(err);

    /* 拒绝新连接，如果已有客户端 */
    if (client_pcb != NULL)
    {
        tcp_abort(newpcb);
        return ERR_ABRT;
    }

    /* 保存客户端PCB */
    client_pcb = newpcb;

    /* 设置接收回调 */
    tcp_recv(client_pcb, tcp_server_recv);

    /* 设置发送完成回调（可选） */
    tcp_sent(client_pcb, tcp_server_sent);

    /* 设置错误回调 */
    tcp_err(client_pcb, tcp_server_err);

    log_w("Client connected: %s:%d\n", ipaddr_ntoa(&client_pcb->remote_ip), client_pcb->remote_port);

    return ERR_OK;
}

/**
 * @brief  数据接收回调
 * @param  arg: 用户参数
 * @param  tpcb: TCP控制块
 * @param  p: 接收到的数据pbuf
 * @param  err: 错误码
 * @retval err_t: 错误码
 */
static err_t tcp_server_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
    LWIP_UNUSED_ARG(arg);

    if (p == NULL)
    {
        /* 连接关闭 */
        log_w("Client disconnected\n");
        client_pcb = NULL;
        return ERR_OK;
    }

    if (err != ERR_OK)
    {
        /* 接收错误 */
        log_e("Receive error: %d\n", err);
        pbuf_free(p);
        return err;
    }

    /* 确认接收到的数据 */
    tcp_recved(tpcb, p->tot_len);

    /* 处理接收到的数据 - 这里调用你的数据处理接口 */
    process_received_data(tpcb, p);

    /* 释放pbuf */
    pbuf_free(p);

    return ERR_OK;
}

/**
 * @brief  发送完成回调（可选）
 * @param  arg: 用户参数
 * @param  tpcb: TCP控制块
 * @param  len: 发送的字节数
 * @retval err_t: 错误码
 */
static err_t tcp_server_sent(void *arg, struct tcp_pcb *tpcb, u16_t len)
{
    LWIP_UNUSED_ARG(arg);
    LWIP_UNUSED_ARG(tpcb);
    LWIP_UNUSED_ARG(len);

    /* 可以在这里实现发送完成后的处理 */
    return ERR_OK;
}

/**
 * @brief  错误回调
 * @param  arg: 用户参数
 * @param  err: 错误码
 * @retval None
 */
static void tcp_server_err(void *arg, err_t err)
{
    LWIP_UNUSED_ARG(arg);
    LWIP_UNUSED_ARG(err);

    log_e("TCP connection error: %d\n", err);
    client_pcb = NULL;
}

/**
 * @brief  数据处理接口（示例）
 * @param  tpcb: TCP控制块
 * @param  p: 接收到的数据pbuf
 * @retval None
 */
static void process_received_data(struct tcp_pcb *tpcb, struct pbuf *p)
{
    /* 这里实现你的数据处理逻辑 */
    log_i("Received %d bytes of data", p->tot_len);
    log_i("Data: %s", (char *)p->payload);
    /* 示例：回显数据 */
    tcp_write(tpcb, p->payload, p->len, TCP_WRITE_FLAG_COPY);
}

/**
 * @brief  初始化TCP服务端任务
 * @retval None
 */
void tcp_server_init(void)
{
    // 等待网络就绪
    while (!netif_is_up(&gnetif))
    {
        vTaskDelay(pdMS_TO_TICKS(500));
    }
    taskENTER_CRITICAL();
    xTaskCreate((TaskFunction_t)tcp_server_task,     // 任务函数
                (const char *)"tcp_server",          // 任务名称
                (uint16_t)TCP_SERVER_STACK_SIZE,     // 任务堆栈大小
                (void *)NULL,                        // 任务参数
                (UBaseType_t)TCP_SERVER_PRIORITY,    // 任务优先级
                (TaskHandle_t *)&TCP_Server_Handle); // 任务句句柄
    taskEXIT_CRITICAL();
}
